import {
  IsString,
  IsEmail,
  IsOptional,
  IsEnum,
  IsBoolean,
  IsArray,
  IsUUID,
  IsInt,
  IsUrl,
  IsDateString,
  MinLength,
  MaxLength,
  Min,
  Max,
  Matches,
  ValidateNested,
  ArrayMinSize,
  ArrayMaxSize,
  IsPhoneNumber
} from 'class-validator'
import { Type, Transform, Expose, Exclude } from 'class-transformer'
import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger'
import { BaseDto, PaginationDto } from './base.dto'
import { IsStrongPassword, IsValidUsername } from '../validators/custom.validator'
import { UserRole } from '@prisma/client'

/**
 * 用户状态枚举
 */
export enum UserStatus {
  ACTIVE = 'active',
  INACTIVE = 'inactive',
  SUSPENDED = 'suspended',
  BANNED = 'banned',
  PENDING = 'pending'
}

/**
 * 用户性别枚举
 */
export enum UserGender {
  MALE = 'male',
  FEMALE = 'female',
  OTHER = 'other',
  PREFER_NOT_TO_SAY = 'prefer_not_to_say'
}

/**
 * 用户注册DTO
 */
export class RegisterUserDto {
  @ApiProperty({ description: '用户名' })
  @IsString()
  @IsValidUsername()
  @MinLength(3)
  @MaxLength(30)
  username: string

  @ApiProperty({ description: '邮箱地址' })
  @IsEmail()
  @MaxLength(100)
  email: string

  @ApiProperty({ description: '密码' })
  @IsString()
  @IsStrongPassword()
  @MinLength(8)
  @MaxLength(128)
  password: string

  @ApiProperty({ description: '确认密码' })
  @IsString()
  confirmPassword: string

  @ApiPropertyOptional({ description: '昵称' })
  @IsOptional()
  @IsString()
  @MaxLength(50)
  nickname?: string

  @ApiPropertyOptional({ description: '手机号码' })
  @IsOptional()
  @IsPhoneNumber('CN')
  phone?: string

  @ApiPropertyOptional({ description: '邀请码' })
  @IsOptional()
  @IsString()
  @MaxLength(20)
  inviteCode?: string

  @ApiPropertyOptional({ description: '同意服务条款' })
  @IsOptional()
  @IsBoolean()
  agreeToTerms?: boolean

  @ApiPropertyOptional({ description: '同意隐私政策' })
  @IsOptional()
  @IsBoolean()
  agreeToPrivacy?: boolean

  @ApiPropertyOptional({ description: '订阅营销邮件' })
  @IsOptional()
  @IsBoolean()
  subscribeNewsletter?: boolean
}

/**
 * 用户登录DTO
 */
export class LoginUserDto {
  @ApiProperty({ description: '用户名或邮箱' })
  @IsString()
  @MinLength(3)
  @MaxLength(100)
  identifier: string

  @ApiProperty({ description: '密码' })
  @IsString()
  @MinLength(1)
  @MaxLength(128)
  password: string

  @ApiPropertyOptional({ description: '记住我' })
  @IsOptional()
  @IsBoolean()
  rememberMe?: boolean

  @ApiPropertyOptional({ description: '验证码' })
  @IsOptional()
  @IsString()
  @MaxLength(10)
  captcha?: string

  @ApiPropertyOptional({ description: '双因素认证代码' })
  @IsOptional()
  @IsString()
  @Matches(/^\d{6}$/)
  twoFactorCode?: string
}

/**
 * 创建用户DTO（管理员用）
 */
export class CreateUserDto {
  @ApiProperty({ description: '用户名' })
  @IsString()
  @IsValidUsername()
  @MinLength(3)
  @MaxLength(30)
  username: string

  @ApiProperty({ description: '邮箱地址' })
  @IsEmail()
  @MaxLength(100)
  email: string

  @ApiProperty({ description: '密码' })
  @IsString()
  @IsStrongPassword()
  @MinLength(8)
  @MaxLength(128)
  password: string

  @ApiPropertyOptional({ description: '昵称' })
  @IsOptional()
  @IsString()
  @MaxLength(50)
  nickname?: string

  @ApiProperty({
    description: '用户角色',
    enum: UserRole,
    default: UserRole.USER
  })
  @IsEnum(UserRole)
  role: UserRole = UserRole.USER

  @ApiProperty({
    description: '用户状态',
    enum: UserStatus,
    default: UserStatus.ACTIVE
  })
  @IsEnum(UserStatus)
  status: UserStatus = UserStatus.ACTIVE

  @ApiPropertyOptional({ description: '手机号码' })
  @IsOptional()
  @IsPhoneNumber('CN')
  phone?: string

  @ApiPropertyOptional({ description: '头像URL' })
  @IsOptional()
  @IsUrl()
  avatar?: string

  @ApiPropertyOptional({ description: '个人简介' })
  @IsOptional()
  @IsString()
  @MaxLength(500)
  bio?: string

  @ApiPropertyOptional({ description: '是否跳过邮箱验证' })
  @IsOptional()
  @IsBoolean()
  skipEmailVerification?: boolean

  @ApiPropertyOptional({ description: '是否发送欢迎邮件' })
  @IsOptional()
  @IsBoolean()
  sendWelcomeEmail?: boolean
}

/**
 * 更新用户DTO
 */
export class UpdateUserDto extends PartialType(CreateUserDto) {
  @ApiPropertyOptional({ description: '更新原因' })
  @IsOptional()
  @IsString()
  @MaxLength(200)
  updateReason?: string

  @Exclude()
  password?: never
}

/**
 * 社交媒体链接DTO
 */
export class SocialLinksDto {
  @ApiPropertyOptional({ description: '微博' })
  @IsOptional()
  @IsUrl()
  weibo?: string

  @ApiPropertyOptional({ description: '微信' })
  @IsOptional()
  @IsString()
  @MaxLength(50)
  wechat?: string

  @ApiPropertyOptional({ description: 'QQ' })
  @IsOptional()
  @IsString()
  @MaxLength(20)
  qq?: string

  @ApiPropertyOptional({ description: 'GitHub' })
  @IsOptional()
  @IsUrl()
  github?: string

  @ApiPropertyOptional({ description: 'Twitter' })
  @IsOptional()
  @IsUrl()
  twitter?: string

  @ApiPropertyOptional({ description: 'LinkedIn' })
  @IsOptional()
  @IsUrl()
  linkedin?: string
}

/**
 * 隐私设置DTO
 */
export class PrivacySettingsDto {
  @ApiPropertyOptional({ description: '显示邮箱' })
  @IsOptional()
  @IsBoolean()
  showEmail?: boolean

  @ApiPropertyOptional({ description: '显示手机号' })
  @IsOptional()
  @IsBoolean()
  showPhone?: boolean

  @ApiPropertyOptional({ description: '显示生日' })
  @IsOptional()
  @IsBoolean()
  showBirthday?: boolean

  @ApiPropertyOptional({ description: '显示在线状态' })
  @IsOptional()
  @IsBoolean()
  showOnlineStatus?: boolean

  @ApiPropertyOptional({ description: '允许搜索' })
  @IsOptional()
  @IsBoolean()
  allowSearch?: boolean

  @ApiPropertyOptional({ description: '允许关注' })
  @IsOptional()
  @IsBoolean()
  allowFollow?: boolean
}

/**
 * 通知设置DTO
 */
export class NotificationSettingsDto {
  @ApiPropertyOptional({ description: '邮件通知' })
  @IsOptional()
  @IsBoolean()
  emailNotifications?: boolean

  @ApiPropertyOptional({ description: '短信通知' })
  @IsOptional()
  @IsBoolean()
  smsNotifications?: boolean

  @ApiPropertyOptional({ description: '推送通知' })
  @IsOptional()
  @IsBoolean()
  pushNotifications?: boolean

  @ApiPropertyOptional({ description: '系统通知' })
  @IsOptional()
  @IsBoolean()
  systemNotifications?: boolean

  @ApiPropertyOptional({ description: '营销邮件' })
  @IsOptional()
  @IsBoolean()
  marketingEmails?: boolean

  @ApiPropertyOptional({ description: '安全通知' })
  @IsOptional()
  @IsBoolean()
  securityNotifications?: boolean
}

/**
 * 更新用户资料DTO
 */
export class UpdateProfileDto {
  @ApiPropertyOptional({ description: '昵称' })
  @IsOptional()
  @IsString()
  @MaxLength(50)
  nickname?: string

  @ApiPropertyOptional({ description: '个人简介' })
  @IsOptional()
  @IsString()
  @MaxLength(500)
  bio?: string

  @ApiPropertyOptional({ description: '头像URL' })
  @IsOptional()
  @IsUrl()
  avatar?: string

  @ApiPropertyOptional({ description: '手机号码' })
  @IsOptional()
  @IsPhoneNumber('CN')
  phone?: string

  @ApiPropertyOptional({ description: '性别', enum: UserGender })
  @IsOptional()
  @IsEnum(UserGender)
  gender?: UserGender

  @ApiPropertyOptional({ description: '生日' })
  @IsOptional()
  @IsDateString()
  birthday?: string

  @ApiPropertyOptional({ description: '所在城市' })
  @IsOptional()
  @IsString()
  @MaxLength(50)
  city?: string

  @ApiPropertyOptional({ description: '个人网站' })
  @IsOptional()
  @IsUrl()
  website?: string

  @ApiPropertyOptional({ description: '社交媒体链接' })
  @IsOptional()
  @ValidateNested()
  @Type(() => SocialLinksDto)
  socialLinks?: SocialLinksDto

  @ApiPropertyOptional({ description: '隐私设置' })
  @IsOptional()
  @ValidateNested()
  @Type(() => PrivacySettingsDto)
  privacySettings?: PrivacySettingsDto

  @ApiPropertyOptional({ description: '通知设置' })
  @IsOptional()
  @ValidateNested()
  @Type(() => NotificationSettingsDto)
  notificationSettings?: NotificationSettingsDto
}

/**
 * 修改密码DTO
 */
export class ChangePasswordDto {
  @ApiProperty({ description: '当前密码' })
  @IsString()
  @MinLength(1)
  currentPassword: string

  @ApiProperty({ description: '新密码' })
  @IsString()
  @IsStrongPassword()
  @MinLength(8)
  @MaxLength(128)
  newPassword: string

  @ApiProperty({ description: '确认新密码' })
  @IsString()
  confirmNewPassword: string
}

/**
 * 重置密码DTO
 */
export class ResetPasswordDto {
  @ApiProperty({ description: '重置令牌' })
  @IsString()
  token: string

  @ApiProperty({ description: '新密码' })
  @IsString()
  @IsStrongPassword()
  @MinLength(8)
  @MaxLength(128)
  newPassword: string

  @ApiProperty({ description: '确认新密码' })
  @IsString()
  confirmNewPassword: string
}

/**
 * 忘记密码DTO
 */
export class ForgotPasswordDto {
  @ApiProperty({ description: '邮箱地址' })
  @IsEmail()
  email: string

  @ApiPropertyOptional({ description: '验证码' })
  @IsOptional()
  @IsString()
  @MaxLength(10)
  captcha?: string
}

/**
 * 查询用户DTO
 */
export class QueryUserDto extends PaginationDto {
  @ApiPropertyOptional({ description: '搜索关键词' })
  @IsOptional()
  @IsString()
  @MaxLength(100)
  search?: string = ''

  @ApiPropertyOptional({
    description: '用户状态',
    enum: UserStatus
  })
  @IsOptional()
  @IsEnum(UserStatus)
  status?: UserStatus

  @ApiPropertyOptional({
    description: '用户角色',
    enum: UserRole
  })
  @IsOptional()
  @IsEnum(UserRole)
  role?: UserRole

  @ApiPropertyOptional({ description: '是否已验证邮箱' })
  @IsOptional()
  @Transform(({ value }) => value === 'true')
  @IsBoolean()
  emailVerified?: boolean

  @ApiPropertyOptional({ description: '是否启用双因素认证' })
  @IsOptional()
  @Transform(({ value }) => value === 'true')
  @IsBoolean()
  twoFactorEnabled?: boolean

  @ApiPropertyOptional({ description: '注册开始时间' })
  @IsOptional()
  @IsDateString()
  registeredAfter?: string

  @ApiPropertyOptional({ description: '注册结束时间' })
  @IsOptional()
  @IsDateString()
  registeredBefore?: string

  @ApiPropertyOptional({ description: '最后登录开始时间' })
  @IsOptional()
  @IsDateString()
  lastLoginAfter?: string

  @ApiPropertyOptional({ description: '最后登录结束时间' })
  @IsOptional()
  @IsDateString()
  lastLoginBefore?: string

  @ApiPropertyOptional({ description: '是否在线' })
  @IsOptional()
  @Transform(({ value }) => value === 'true')
  @IsBoolean()
  isOnline?: boolean

  @ApiPropertyOptional({ description: '性别', enum: UserGender })
  @IsOptional()
  @IsEnum(UserGender)
  gender?: UserGender

  @ApiPropertyOptional({ description: '所在城市' })
  @IsOptional()
  @IsString()
  @MaxLength(50)
  city?: string

  @ApiPropertyOptional({ description: '年龄范围最小值' })
  @IsOptional()
  @Transform(({ value }) => parseInt(value))
  @IsInt()
  @Min(0)
  @Max(150)
  minAge?: number

  @ApiPropertyOptional({ description: '年龄范围最大值' })
  @IsOptional()
  @Transform(({ value }) => parseInt(value))
  @IsInt()
  @Min(0)
  @Max(150)
  maxAge?: number
}

/**
 * 用户响应DTO
 */
export class UserResponseDto extends BaseDto {
  @ApiProperty({ description: '用户名' })
  @Expose()
  username: string

  @ApiProperty({ description: '邮箱地址' })
  @Expose()
  email: string

  @ApiPropertyOptional({ description: '昵称' })
  @Expose()
  nickname?: string

  @ApiProperty({ description: '用户角色', enum: UserRole })
  @Expose()
  role: UserRole

  @ApiProperty({ description: '用户状态', enum: UserStatus })
  @Expose()
  status: UserStatus

  @ApiPropertyOptional({ description: '头像URL' })
  @Expose()
  avatar?: string

  @ApiPropertyOptional({ description: '个人简介' })
  @Expose()
  bio?: string

  @ApiPropertyOptional({ description: '手机号码' })
  @Expose()
  phone?: string

  @ApiPropertyOptional({ description: '性别', enum: UserGender })
  @Expose()
  gender?: UserGender

  @ApiPropertyOptional({ description: '生日' })
  @Expose()
  birthday?: Date

  @ApiPropertyOptional({ description: '所在城市' })
  @Expose()
  city?: string

  @ApiPropertyOptional({ description: '个人网站' })
  @Expose()
  website?: string

  @ApiProperty({ description: '是否已验证邮箱' })
  @Expose()
  emailVerified: boolean

  @ApiProperty({ description: '邮箱验证时间' })
  @Expose()
  emailVerifiedAt?: Date

  @ApiProperty({ description: '是否启用双因素认证' })
  @Expose()
  twoFactorEnabled: boolean

  @ApiProperty({ description: '最后登录时间' })
  @Expose()
  lastLoginAt?: Date

  @ApiProperty({ description: '最后登录IP' })
  @Expose()
  lastLoginIp?: string

  @ApiProperty({ description: '登录次数' })
  @Expose()
  loginCount: number

  @ApiProperty({ description: '是否在线' })
  @Expose()
  isOnline: boolean

  @ApiProperty({ description: '最后活动时间' })
  @Expose()
  lastActiveAt?: Date

  @ApiProperty({ description: '内容数量' })
  @Expose()
  contentCount: number

  @ApiProperty({ description: '关注者数量' })
  @Expose()
  followersCount: number

  @ApiProperty({ description: '关注数量' })
  @Expose()
  followingCount: number

  @ApiPropertyOptional({ description: '社交媒体链接' })
  @Expose()
  socialLinks?: SocialLinksDto

  @ApiPropertyOptional({ description: '隐私设置' })
  @Expose()
  privacySettings?: PrivacySettingsDto

  @ApiPropertyOptional({ description: '通知设置' })
  @Expose()
  notificationSettings?: NotificationSettingsDto

  @ApiPropertyOptional({ description: '用户偏好设置' })
  @Expose()
  preferences?: Record<string, any>

  @ApiPropertyOptional({ description: '用户标签' })
  @Expose()
  tags?: string[]

  @ApiProperty({ description: '账户积分' })
  @Expose()
  points: number

  @ApiProperty({ description: '账户等级' })
  @Expose()
  level: number

  @ApiProperty({ description: '经验值' })
  @Expose()
  experience: number

  @ApiPropertyOptional({ description: '邀请码' })
  @Expose()
  inviteCode?: string

  @ApiProperty({ description: '邀请人数' })
  @Expose()
  inviteCount: number

  @ApiPropertyOptional({ description: '邀请者信息' })
  @Expose()
  inviter?: {
    id: string
    username: string
    nickname: string
  }

  @ApiProperty({ description: '账户余额' })
  @Expose()
  balance: number

  @ApiProperty({ description: '会员到期时间' })
  @Expose()
  membershipExpiresAt?: Date

  @ApiProperty({ description: '是否为VIP' })
  @Expose()
  isVip: boolean

  @ApiPropertyOptional({ description: '最近内容' })
  @Expose()
  recentContent?: Array<{
    id: string
    title: string
    slug: string
    createdAt: Date
  }>

  @Exclude()
  password: never

  @Exclude()
  twoFactorSecret: never

  @Exclude()
  resetPasswordToken: never

  @Exclude()
  emailVerificationToken: never
}

/**
 * 用户简要信息DTO
 */
export class UserBriefDto {
  @ApiProperty({ description: '用户ID' })
  @Expose()
  id: string

  @ApiProperty({ description: '用户名' })
  @Expose()
  username: string

  @ApiPropertyOptional({ description: '昵称' })
  @Expose()
  nickname?: string

  @ApiPropertyOptional({ description: '头像URL' })
  @Expose()
  avatar?: string

  @ApiProperty({ description: '用户角色', enum: UserRole })
  @Expose()
  role: UserRole

  @ApiProperty({ description: '用户状态', enum: UserStatus })
  @Expose()
  status: UserStatus

  @ApiProperty({ description: '是否在线' })
  @Expose()
  isOnline: boolean

  @ApiProperty({ description: '最后活动时间' })
  @Expose()
  lastActiveAt?: Date
}

/**
 * 用户统计DTO
 */
export class UserStatsDto {
  @ApiProperty({ description: '总用户数' })
  @Expose()
  totalUsers: number

  @ApiProperty({ description: '活跃用户数' })
  @Expose()
  activeUsers: number

  @ApiProperty({ description: '在线用户数' })
  @Expose()
  onlineUsers: number

  @ApiProperty({ description: '今日新增用户' })
  @Expose()
  todayNewUsers: number

  @ApiProperty({ description: '本周新增用户' })
  @Expose()
  weekNewUsers: number

  @ApiProperty({ description: '本月新增用户' })
  @Expose()
  monthNewUsers: number

  @ApiProperty({ description: '按角色统计' })
  @Expose()
  byRole: Record<UserRole, number>

  @ApiProperty({ description: '按状态统计' })
  @Expose()
  byStatus: Record<UserStatus, number>

  @ApiProperty({ description: '按性别统计' })
  @Expose()
  byGender: Record<UserGender, number>

  @ApiProperty({ description: '邮箱验证统计' })
  @Expose()
  emailVerification: {
    verified: number
    unverified: number
    rate: number
  }

  @ApiProperty({ description: '双因素认证统计' })
  @Expose()
  twoFactorAuth: {
    enabled: number
    disabled: number
    rate: number
  }

  @ApiProperty({ description: '最活跃用户' })
  @Expose()
  mostActiveUsers: Array<{
    id: string
    username: string
    nickname: string
    contentCount: number
    loginCount: number
  }>

  @ApiProperty({ description: '最近注册用户' })
  @Expose()
  recentUsers: Array<{
    id: string
    username: string
    nickname: string
    createdAt: Date
    status: UserStatus
  }>

  @ApiProperty({ description: '用户增长趋势' })
  @Expose()
  growthTrend: Array<{
    date: string
    newUsers: number
    totalUsers: number
  }>
}

/**
 * 批量用户操作DTO
 */
export class BulkUserOperationDto {
  @ApiProperty({
    description: '操作类型',
    enum: ['activate', 'deactivate', 'suspend', 'ban', 'delete', 'change_role', 'verify_email']
  })
  @IsEnum(['activate', 'deactivate', 'suspend', 'ban', 'delete', 'change_role', 'verify_email'])
  operation: string

  @ApiProperty({ description: '用户ID列表' })
  @IsArray()
  @IsUUID(4, { each: true })
  @ArrayMinSize(1)
  @ArrayMaxSize(100)
  items: string[]

  @ApiPropertyOptional({ description: '操作参数' })
  @IsOptional()
  params?: {
    role?: UserRole
    status?: UserStatus
    reason?: string
    [key: string]: any
  }

  @ApiPropertyOptional({ description: '操作原因' })
  @IsOptional()
  @IsString()
  @MaxLength(200)
  reason?: string

  @ApiPropertyOptional({ description: '是否发送通知' })
  @IsOptional()
  @IsBoolean()
  sendNotification?: boolean
}

/**
 * 用户活动记录DTO
 */
export class UserActivityDto {
  @ApiProperty({ description: '活动ID' })
  @Expose()
  id: string

  @ApiProperty({ description: '活动类型' })
  @Expose()
  type: string

  @ApiProperty({ description: '活动描述' })
  @Expose()
  description: string

  @ApiPropertyOptional({ description: '活动详情' })
  @Expose()
  details?: Record<string, any>

  @ApiProperty({ description: 'IP地址' })
  @Expose()
  ipAddress: string

  @ApiProperty({ description: '用户代理' })
  @Expose()
  userAgent: string

  @ApiProperty({ description: '活动时间' })
  @Expose()
  createdAt: Date

  @ApiPropertyOptional({ description: '地理位置' })
  @Expose()
  location?: {
    country: string
    region: string
    city: string
  }

  @ApiPropertyOptional({ description: '设备信息' })
  @Expose()
  device?: {
    type: string
    os: string
    browser: string
  }
}

/**
 * 用户导出DTO
 */
export class UserExportDto {
  @ApiPropertyOptional({ description: '导出格式' })
  @IsOptional()
  @IsEnum(['csv', 'xlsx', 'json'])
  format?: string = 'csv'

  @ApiPropertyOptional({ description: '导出字段' })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  fields?: string[]

  @ApiPropertyOptional({ description: '过滤条件' })
  @IsOptional()
  @ValidateNested()
  @Type(() => QueryUserDto)
  filters?: QueryUserDto

  @ApiPropertyOptional({ description: '是否包含敏感信息' })
  @IsOptional()
  @IsBoolean()
  includeSensitive?: boolean
}

/**
 * 用户导入DTO
 */
export class UserImportDto {
  @ApiProperty({ description: '导入文件URL或Base64' })
  @IsString()
  file: string

  @ApiPropertyOptional({ description: '文件格式' })
  @IsOptional()
  @IsEnum(['csv', 'xlsx', 'json'])
  format?: string = 'csv'

  @ApiPropertyOptional({ description: '是否跳过重复用户' })
  @IsOptional()
  @IsBoolean()
  skipDuplicates?: boolean = true

  @ApiPropertyOptional({ description: '是否发送欢迎邮件' })
  @IsOptional()
  @IsBoolean()
  sendWelcomeEmail?: boolean = false

  @ApiPropertyOptional({ description: '默认角色' })
  @IsOptional()
  @IsEnum(UserRole)
  defaultRole?: UserRole = UserRole.USER

  @ApiPropertyOptional({ description: '默认状态' })
  @IsOptional()
  @IsEnum(UserStatus)
  defaultStatus?: UserStatus = UserStatus.ACTIVE

  @ApiPropertyOptional({ description: '字段映射' })
  @IsOptional()
  fieldMapping?: Record<string, string>
}
